﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WebPrinter.Library.DaQu.Params;
using WebPrinter.Library.DaQu.Result;
using WebPrinter.Library.DaQu.Util;

namespace WebPrinter.Library.DaQu
{
    internal class DaquPrinterClient : IPrinterClient
    {
        private readonly string _appId;
        private readonly string _appSecret;
        private const string ApiPrefix = "https://iot-device.trenditiot.com/openapi";

        /// <summary>
        /// 构造函数，初始化大趋打印机客户端。
        /// </summary>
        /// <param name="appId">开发者AppId</param>
        /// <param name="appSecret">开发者AppSecret</param>
        public DaquPrinterClient(string appId, string appSecret)
        {
            _appId = appId;
            _appSecret = appSecret;
        }

        private PApiResult<bool> ToBoolResult<T>(ResponseResult<T> result)
        {
            return new PApiResult<bool>
            {
                Code = result?.Code == "0" ? 0 : -1,
                Message = result?.Message,
                Data = result?.Code == "0"
            };
        }

        /// <inheritdoc />
        public async Task<PApiResult<bool>> AddPrinterAsync(string printerSn, string printerKey, string printerName)
        {
            // 绑定打印机
            var param = new List<PrinterAddParam>
            {
                new PrinterAddParam { Sn = printerSn, Key = printerKey, Name = printerName }
            };
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<PrinterAddResultData>, List<PrinterAddParam>>(
                ApiPrefix + "/addPrinter", param, _appId, _appSecret);
            return ToBoolResult(result);
        }

        /// <inheritdoc />
        public async Task<PApiResult<bool>> PrintReceiptAsync(string printerSn, string content)
        {
            // 打印小票
            var param = new PrintParam { Sn = printerSn, Content = content };
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<PrintRequestResultData>, PrintParam>(
                ApiPrefix + "/print", param, _appId, _appSecret);
            return ToBoolResult(result);
        }

        /// <inheritdoc />
        public async Task<PApiResult<bool>> CleanWaitingQueueAsync(string printerSn)
        {
            // 清空设备待打印队列
            var param = new SnParam(printerSn);
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<CleanQueueResultData>, SnParam>(
                ApiPrefix + "/cleanWaitingQueue", param, _appId, _appSecret);
            return ToBoolResult(result);
        }

        /// <inheritdoc />
        public async Task<PApiResult<bool>> DeletePrinterAsync(string printerSn)
        {
            // 解绑打印机
            var param = new List<string> { printerSn };
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<PrinterUnbindResultData>, List<string>>(
                ApiPrefix + "/delPrinter", param, _appId, _appSecret);
            return ToBoolResult(result);
        }

        /// <inheritdoc />
        public async Task<PApiResult<bool>> EditPrinterAsync(string printerSn, string newName)
        {
            // 修改打印机信息
            var param = new PrinterAddParam { Sn = printerSn, Name = newName };
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<object>, PrinterAddParam>(
                ApiPrefix + "/editPrinter", param, _appId, _appSecret);
            return ToBoolResult(result);
        }

        /// <inheritdoc />
        public async Task<PApiResult<string>> GetDeviceStatusAsync(string printerSn)
        {
            // 查询打印机状态
            var param = new SnParam(printerSn);
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<PrinterStatusResultData>, SnParam>(
                ApiPrefix + "/getDeviceStatus", param, _appId, _appSecret);
            return new PApiResult<string>
            {
                Code = result?.Code == "0" ? 0 : -1,
                Message = result?.Message,
                Data = result?.Data?.WorkStatusDesc
            };
        }

        /// <inheritdoc />
        public async Task<PApiResult<string>> GetPrintStatusAsync(string printerSn, string orderId)
        {
            // 查询小票打印状态
            var param = new PrintStatusQueryParam(printerSn, long.Parse(orderId));
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<PrintStatusData>, PrintStatusQueryParam>(
                ApiPrefix + "/getPrintStatus", param, _appId, _appSecret);
            return new PApiResult<string>
            {
                Code = result?.Code == "0" ? 0 : -1,
                Message = result?.Message,
                Data = result?.Data?.Status
            };
        }

        /// <inheritdoc />
        public async Task<PApiResult<bool>> PlayPayInVoiceAsync(string printerSn, string text)
        {
            // 播放收银语音
            var param = new { sn = printerSn, text = text };
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<object>, object>(
                ApiPrefix + "/payInVoice", param, _appId, _appSecret);
            return ToBoolResult(result);
        }

        /// <inheritdoc />
        public async Task<PApiResult<bool>> SetDensityAsync(string printerSn, int density)
        {
            // 设置打印浓度
            var param = new { sn = printerSn, density = density };
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<object>, object>(
                ApiPrefix + "/setDensity", param, _appId, _appSecret);
            return ToBoolResult(result);
        }

        /// <inheritdoc />
        public async Task<PApiResult<bool>> SetImageAsync(string printerSn, byte[] imageData)
        {
            // 打印图片设置
            var param = new { sn = printerSn, image = Convert.ToBase64String(imageData) };
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<object>, object>(
                ApiPrefix + "/setImage", param, _appId, _appSecret);
            return ToBoolResult(result);
        }

        /// <inheritdoc />
        public async Task<PApiResult<bool>> SetPrintSpeedAsync(string printerSn, int speed)
        {
            // 设置打印速度
            var param = new { sn = printerSn, speed = speed };
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<object>, object>(
                ApiPrefix + "/setPrintSpeed", param, _appId, _appSecret);
            return ToBoolResult(result);
        }

        /// <inheritdoc />
        public async Task<PApiResult<bool>> SetVolumeAsync(string printerSn, int volume)
        {
            // 设置音量
            var param = new { sn = printerSn, volume = volume };
            var result = await DaQuRequestUtils.PostAsync<ResponseResult<object>, object>(
                ApiPrefix + "/setVolume", param, _appId, _appSecret);
            return ToBoolResult(result);
        }
    }
}
